﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MathNet.Numerics.Distributions;
using OnlineScheduling.DomainModel;

namespace OnlineScheduling
{
    public partial class Main : Form
    {
        private List<Instance> instances=new List<Instance>();
        private NormalDistribution normal;
        private int[] Wyniki = {0, 0, 0, 0};
        public Main()
        {
            InitializeComponent();
        }

        private void buttonGenerate_Click(object sender, EventArgs e)
        {
            instances.Clear();
            ClearResults();
            comboBoxInstanceId.Items.Clear();

            if (!checkBox1.Checked)
            {
                for (int i = 0; i < (int) numericUpDownSimulations.Value; i++)
                {
                    instances.Add(new Instance(
                                      (int) numericUpDownTasksNumber.Value,
                                      (int) numericUpDownProcessors.Value,
                                      TasksPriorityType.ByArrivalTime,
                                      (int) numericUpDownMinDuration.Value,
                                      (int) numericUpDownMaxDuration.Value,
                                      (int) numericUpDownMinArrival.Value,
                                      (int) numericUpDownMaxArrival.Value,
                                      (int) numericUpDownMinWeight.Value,
                                      (int) numericUpDownMaxWeight.Value,null
                                      ));
                    comboBoxInstanceId.Items.Add(i);
                }
            }
            else
            {
                normal=new NormalDistribution((int)numericUpDownMU.Value,(int)numericUpDownSigma.Value);
                for (int i = 0; i < (int)numericUpDownSimulations.Value; i++)
                {
                    instances.Add(new Instance(
                                      (int)numericUpDownTasksNumber.Value,
                                      (int)numericUpDownProcessors.Value,
                                      TasksPriorityType.ByArrivalTime,
                                      (int)numericUpDownMinDuration.Value,
                                      (int)numericUpDownMaxDuration.Value,
                                      (int)numericUpDownMinArrival.Value,
                                      (int)numericUpDownMaxArrival.Value,
                                      (int)numericUpDownMinWeight.Value,
                                      (int)numericUpDownMaxWeight.Value,normal
                                      ));
                    comboBoxInstanceId.Items.Add(i);
                }
            }

            taskBindingSource.DataSource = null;

            comboBoxInstanceId.Enabled = true;
            comboBoxInstanceId.SelectedIndex = 0;

            dataGridViewTasks.DataSource = taskBindingSource;
        }

        private void ClearResults()
        {
            Wyniki[0] = 0;
            Wyniki[1] = 0;
            Wyniki[2] = 0;
            Wyniki[3] = 0;
        }


        private void comboBoxInstanceId_SelectedIndexChanged(object sender, EventArgs e)
        {
            taskBindingSource.DataSource = instances[comboBoxInstanceId.SelectedIndex].GetCopyList();
        }

        private void buttonRunWD_Click(object sender, EventArgs e)
        {
            textBoxWDResults.Clear();
            double Sum = 0.0;
            List<Instance> myOwnCopy = StaticHelper.GiveMePrivateCopyOfInstances(instances);

            foreach (var instance in myOwnCopy)
            {
                NPHighDensinitySolver highDenisitySolver = new NPHighDensinitySolver(instance);
                highDenisitySolver.Run();
                textBoxWDResults.AppendText(highDenisitySolver.WeightedSum.ToString() + Environment.NewLine);
                Sum += highDenisitySolver.WeightedSum;
            }
            textBoxWDAverage.Text = (Sum / myOwnCopy.Count).ToString();

            UpdateButton();
        }

        private void UpdateButton()
        {
            button1.Enabled = textBoxWDAverage.Text != string.Empty && textBox1WSPTRAverage.Text != string.Empty
                              && textBoxWeightBySRTAverage.Text != string.Empty &&
                              textBox1z3Average.Text != string.Empty;
        }


        private void buttonWeightBySRTF_Click(object sender, EventArgs e)
        {
            textBoxWeightBySRTResults.Clear();
            double Sum = 0.0;
            List<Instance> myOwnCopy = StaticHelper.GiveMePrivateCopyOfInstances(instances);

            foreach (var instance in myOwnCopy)
            {
               WeightBySRTSolver weightBySRTSolver = new WeightBySRTSolver(instance);
                weightBySRTSolver.Run();
                textBoxWeightBySRTResults.AppendText(weightBySRTSolver.WeightedSum.ToString() + Environment.NewLine);
                Sum += weightBySRTSolver.WeightedSum;
            }
            textBoxWeightBySRTAverage.Text = (Sum / myOwnCopy.Count).ToString();
            UpdateButton();
        }

       

        private void buttonWSPTRandom_Click(object sender, EventArgs e)
        {
            textBoxWSPTRandomResults.Clear();
            double Sum = 0.0;
            List<Instance> myOwnCopy = StaticHelper.GiveMePrivateCopyOfInstances(instances);

            foreach (var instance in myOwnCopy)
            {
                NPWSPTRandomizedSolver WSPTRSolver = new NPWSPTRandomizedSolver(instance);
                WSPTRSolver.Run();
                textBoxWSPTRandomResults.AppendText(WSPTRSolver.WeightedSum.ToString() + Environment.NewLine);
                Sum += WSPTRSolver.WeightedSum;
            }
            textBox1WSPTRAverage.Text = (Sum / myOwnCopy.Count).ToString();
            UpdateButton();
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            numericUpDownMinDuration.Enabled = !checkBox1.Checked;
            numericUpDownMaxDuration.Enabled = !checkBox1.Checked;
            numericUpDownMU.Enabled = checkBox1.Checked;
            numericUpDownSigma.Enabled = checkBox1.Checked;
        }

        private void button1z3_Click(object sender, EventArgs e)
        {
            textBox1z3Results.Clear();
            double Sum = 0.0;
            List<Instance> myOwnCopy = StaticHelper.GiveMePrivateCopyOfInstances(instances);

            foreach (var instance in myOwnCopy)
            {
                TotalRandomSolver oneOutOfThreeSolver = new TotalRandomSolver(instance);
                //OneOutOfThreeSolver oneOutOfThreeSolver = new OneOutOfThreeSolver(instance);
                oneOutOfThreeSolver.Run();
                textBox1z3Results.AppendText(oneOutOfThreeSolver.WeightedSum.ToString() + Environment.NewLine);
                Sum += oneOutOfThreeSolver.WeightedSum;
            }
            textBox1z3Average.Text = (Sum / myOwnCopy.Count).ToString();
            UpdateButton();
        }    

        private void WhoIsTheBest(int alg1,int alg2, int alg3, int alg4)
        {
            int min = alg1;
            int id = 0;
            if (alg2<min) 
            {
                min = alg2;
                id = 1;
            }
            if (alg3<min)
            {
                min = alg3;
                id = 2;
            }
            if (alg4<min)
            {
                min = alg4;
                id = 3;
            }

            Wyniki[id]++;
        }

        String Winner(int alg1, int alg2, int alg3, int alg4)
        {
            int min = alg1;
            int id = 0;

            if (alg2 < min)
            {
                min = alg2;
                id = 1;
            }
            if (alg3 < min)
            {
                min = alg3;
                id = 2;
            }
            if (alg4 < min)
            {
                min = alg4;
                id = 3;
            }

            switch (id)
            {
                case 0:
                    return "WSPT";
                case 1:
                    return "average";
                case 2:
                    return "WSTR";
                case 3:
                    return "1z3";
            }
            return "";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ClearResults();
            StreamWriter file = new StreamWriter("Wyniki.txt");

            String[] tablica1 = textBoxWDResults.Lines;
            String[] tablica2 = textBoxWSPTRandomResults.Lines;
            String[] tablica3 = textBoxWeightBySRTResults.Lines;
            String[] tablica4 = textBox1z3Results.Lines;

            for (int i=0; i<(int)numericUpDownSimulations.Value; i++)
            {
                int wynik1 = int.Parse(tablica1[i]);
                int wynik2 = int.Parse(tablica2[i]);
                int wynik3 = int.Parse(tablica3[i]);
                int wynik4 = int.Parse(tablica4[i]);

                WhoIsTheBest(wynik1,wynik2,wynik3,wynik4);
                
                file.WriteLine(tablica1[i] + '\t' + tablica2[i] + '\t' + tablica3[i] + '\t' + tablica4[i] + '\t' + Winner(wynik1,wynik2, wynik3, wynik4));
            }

            file.Close();
            textBox1.Text = Wyniki[0].ToString();
            textBox2.Text = Wyniki[1].ToString();
            textBox3.Text = Wyniki[2].ToString();
            textBox4.Text = Wyniki[3].ToString();
        }
    }
}
